package com.cizzy.relation.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.BooleanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cizzy.relation.entity.vo.FollowRequest;
import com.cizzy.relation.feign.UserFeign;
import com.cizzy.relation.common.Result;
import com.cizzy.relation.common.UserIdHolder;
import com.cizzy.relation.entity.dto.UserDTO;
import com.cizzy.relation.entity.Relation;
import com.cizzy.relation.mapper.RelationMapper;
import com.cizzy.relation.service.IRelationService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import io.seata.spring.annotation.GlobalTransactional;
import org.checkerframework.checker.units.qual.A;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import static com.cizzy.relation.config.CizzyFinal.RELATION_LOCK;
import static com.google.common.util.concurrent.Striped.lock;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author crissy-月下闲人
 * @since 2023-11-03
 */
@Service
public class RelationServiceImpl extends ServiceImpl<RelationMapper, Relation> implements IRelationService {

    @Qualifier("com.cizzy.relation.feign.UserFeign")
    @Autowired
    private UserFeign userFeign;

//    @Resource
    @Autowired
    private RelationMapper relationMapper;

//    @Resource
    @Autowired
    private RedissonClient redissonClient;

    @Override
    public Result<String> toConcern(Long targId) {
        Long userId = UserIdHolder.getUserId();
        QueryWrapper<Relation> wrapper = new QueryWrapper<>();
        wrapper.eq("target_id", targId).eq("user_id", userId);


        //TODO 判断该视频是否已经点赞
        boolean exist = relationMapper.exists(wrapper);
        if (BooleanUtil.isFalse(exist)) {
            //TODO 未关注
            relationMapper.insert(new Relation(userId, targId));
            return Result.success("关注成功", null);
        } else {
            //TODO 已关注
            relationMapper.delete(wrapper);
            return Result.success("取消关注成功", null);
        }
    }

    @Override
    public Result<List<Long>> getTargetIds(Long userId) {
        List<Long> targetIds = relationMapper.selectConcernIds(userId);
        return Result.success(targetIds);
    }

    @Override
    public Result<List<UserDTO>> getTargetUsers(Long userId) {
        List<Long> targetIds = relationMapper.selectConcernIds(userId);
        if (CollectionUtil.isNotEmpty(targetIds)) {
            return userFeign.getUserListByIds(targetIds);
        }
        return Result.success(null);
    }

    @Override
    public Result<List<UserDTO>> getFans(Long userId) {
        List<Long> list = relationMapper.selectFanIds(userId);
        if (CollectionUtil.isNotEmpty(list)) {
            return userFeign.getUserListByIds(list);
        }
        return Result.success(null);
    }

    @GlobalTransactional
    @Override
    public Result<Relation> createFollow(FollowRequest followRequest) {
        RLock lock = redissonClient.getLock(RELATION_LOCK);
        lock.lock();
        Long userId = followRequest.getUserId();
        Long targetId = followRequest.getTargetId();
        if(userId == null || targetId == null) {
            return Result.error("参数错误");
        }
        QueryWrapper<Relation> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId).eq("target_id", targetId);
        boolean exist = relationMapper.exists(wrapper);
        Relation relation = new Relation(userId, targetId);
        System.out.println("---------------------");
        System.out.println(relation);
        if (BooleanUtil.isFalse(exist)) {
            relationMapper.insert(relation);
            userFeign.addUserCountById("follow_count", userId, 1);
            userFeign.addUserCountById("follower_count", targetId, 1);
        }
        lock.unlock();
        if(BooleanUtil.isTrue(exist)) {
            return Result.error("关注失败");
        } else {
            return Result.success(relation);
        }
    }

    @Override
    public Result<Relation> cancelFollow(FollowRequest followRequest) {
        RLock lock = redissonClient.getLock(RELATION_LOCK);
        lock.lock();
        Long userId = followRequest.getUserId();
        Long targetId = followRequest.getTargetId();
        if(userId == null || targetId == null) {
            return Result.error("参数错误");
        }
        QueryWrapper<Relation> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId).eq("target_id", targetId);
        boolean exist = relationMapper.exists(wrapper);
        Relation relation = new Relation(userId, targetId);
        if (BooleanUtil.isTrue(exist)) {
            relationMapper.delete(wrapper);
            userFeign.addUserCountById("follow_count", userId, -1);
            userFeign.addUserCountById("follower_count", targetId, -1);
        }
        lock.unlock();
        if(BooleanUtil.isFalse(exist)) {
            return Result.error("取消关注失败");
        } else {
            return Result.success(relation);
        }
    }

    @Override
    public Result<Boolean> isFollowed(Long userId, Long targetId) {
        if(userId == null || targetId == null) {
            return Result.error("参数错误");
        }
        QueryWrapper<Relation> queryWrapper = new QueryWrapper<Relation>().eq("user_id", userId).eq("target_id", targetId);
        return Result.success(relationMapper.exists(queryWrapper));
    }

    @Override
    public Result<List<UserDTO>> getFollowById(Long userId) {
        if(userId == null) {
            return Result.error("参数错误");
        }
        QueryWrapper<Relation> queryWrapper = new QueryWrapper<Relation>().eq("user_id", userId);
        List<Relation> relationList = relationMapper.selectList(queryWrapper);
        if(relationList == null) {
            return Result.error("关注列表查询失败");
        }
        List<Long> userIdList = relationList.stream().map(Relation::getTargetId).toList();
        List<UserDTO> userDTOList = userFeign.getUserListByIds(userIdList).getData();
        if(userDTOList == null) {
            return Result.error("关注列表查询失败");
        }
        return Result.success(userDTOList);
    }

    @Override
    public Result<List<UserDTO>> getFollowPageById(Long userId, Integer page, Integer pageSize) {
        if(userId == null || page == null || pageSize == null) {
            return Result.error("参数错误");
        }
        QueryWrapper<Relation> queryWrapper = new QueryWrapper<Relation>().
                eq("user_id", userId).last(String.format("LIMIT %d,%d", (page-1) * pageSize,page * pageSize));
        List<Relation> relationList = relationMapper.selectList(queryWrapper);
        if(relationList == null) {
            return Result.error("关注列表查询失败");
        }
        List<Long> userIdList = relationList.stream().map(Relation::getTargetId).toList();
        List<UserDTO> userDTOList = userFeign.getUserListByIds(userIdList).getData();
        if(userDTOList == null) {
            return Result.error("关注列表查询失败");
        }
        return Result.success(userDTOList);
    }

    @Override
    public Result<List<UserDTO>> getFollowerById(Long targetId) {
        if(targetId == null) {
            return Result.error("参数错误");
        }
        QueryWrapper<Relation> queryWrapper = new QueryWrapper<Relation>().eq("target_id", targetId);
        List<Relation> relationList = relationMapper.selectList(queryWrapper);
        if(relationList == null) {
            return Result.error("粉丝列表查询失败");
        }
        List<Long> userIdList = relationList.stream().map(Relation::getTargetId).toList();
        List<UserDTO> userDTOList = userFeign.getUserListByIds(userIdList).getData();
        if(userDTOList == null) {
            return Result.error("粉丝列表查询失败");
        }
        return Result.success(userDTOList);
    }

    @Override
    public Result<List<UserDTO>> getFollowerPageById(Long targetId, Integer page, Integer pageSize) {
        if(targetId == null || page == null || pageSize == null) {
            return Result.error("参数错误");
        }
        QueryWrapper<Relation> queryWrapper = new QueryWrapper<Relation>().
                eq("target_id", targetId).last(String.format("LIMIT %d,%d", (page-1) * pageSize,page * pageSize));
        List<Relation> relationList = relationMapper.selectList(queryWrapper);
        if(relationList == null) {
            return Result.error("粉丝列表查询失败");
        }
        List<Long> userIdList = relationList.stream().map(Relation::getTargetId).toList();
        List<UserDTO> userDTOList = userFeign.getUserListByIds(userIdList).getData();
        if(userDTOList == null) {
            return Result.error("粉丝列表查询失败");
        }
        return Result.success(userDTOList);
    }
}
